package butines.core;

import java.awt.Graphics;
import java.awt.HeadlessException;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.PixelGrabber;
import java.util.HashMap;
import java.util.Map;

import butines.core.Image;

public class ImageManager {

	private static ImageManager instance = new ImageManager();
	
	public static ImageManager getInstance() {
		return instance;
	}
	
	private Map<String, Image> images = new HashMap<String, Image>();

	public Image loadImage(String path) {
		Image image = images.get(path);
		if (image == null) {
			image = new Image(path);
			images.put(path, image);
			System.out.println("[DEBUG] " + getClass().getCanonicalName() + " | load image: " + path);
		}
		return image;
	}

	public Image getImage(String name) {
		Image image = images.get(name);
		if (image == null) {
			System.out.println("[DEBUG] " + getClass().getCanonicalName() + " | image not found: " + name);
		}
		return image;
	}

	public void addImage(String name, Image image) {
		images.put(name, image);
	}
	
	public boolean hasImage(String name) {
		return images.containsKey(name);
	}
	
	public Image loadImage(String path, int numAngles) {
		String name = path + ",numAngles:" + numAngles;
		Image image = null;
		if (hasImage(name)) {
			image = getImage(name);
		}  else {
			image = loadImage(path);
			image = createIsometricImage(image, numAngles);
			addImage(name, image);
		}
		return image;
	}
	
	public Image createIsometricImage(Image image, int numAngle) {
		java.awt.Image rawImage = image.getRawImage();
		int width = rawImage.getWidth(null);
		int height = rawImage.getHeight(null);
		int transparency = getColorModel(rawImage).getTransparency();

		int numOrigem = (numAngle / 2) + 1;
		int widthFrame = (width / numOrigem);
		int newWidth = widthFrame * numAngle;

		int dx1 = width;
		int dx2 = width + (widthFrame * (numOrigem - 2)); 

		int sx1 = widthFrame + (widthFrame * (numOrigem - 2));
		int sx2 = widthFrame;
		
		BufferedImage buffered = createBufferedImage(newWidth, height, transparency);
		Graphics g = buffered.createGraphics();
		 // Desenha a imagem normal
		g.drawImage(rawImage, 0, 0, null);
		 // Desenha a imagem invertida descartando a primeira e ultima imagem
		g.drawImage(rawImage, dx1, 0, dx2, height, sx1, 0, sx2, height, null);
		g.dispose();

		return new Image(buffered);
	}
	
	public BufferedImage createBufferedImage(int width, int height, int transparency) {
		return ScreenManager.createCompatibleImage(width, height, transparency);
	}

	public ColorModel getColorModel(java.awt.Image rawImage) {
		if (rawImage instanceof BufferedImage) {
			BufferedImage bimage = (BufferedImage) rawImage;
			return bimage.getColorModel();
		}
		
		PixelGrabber pg = new PixelGrabber(rawImage, 0, 0, 1, 1, false);
		try {
			pg.grabPixels();
		} catch (InterruptedException e) {
			// ignored
		}

		// Get the image's color model
		return pg.getColorModel();
	}

	public BufferedImage createBufferedImage(java.awt.Image rawImage) {
		int width = rawImage.getWidth(null);
		int height = rawImage.getHeight(null);
		ColorModel colorModel = getColorModel(rawImage);

		BufferedImage buffered = null;
		try {
			buffered = createBufferedImage(width, height, colorModel.getTransparency());
		} catch (HeadlessException e) {
			// The system does not have a screen
		}

		if (buffered == null) {
			int type = colorModel.hasAlpha() ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB; 
			buffered = new BufferedImage(width, height, type);
		}

		Graphics g = buffered.createGraphics();
		g.drawImage(rawImage, 0, 0, null);
		g.dispose();

		return buffered;
	}
	
}
